<template>
    <div class="x">
        <a-card title="rxjs拖拽简易实现，存在计算bug">
            <div id="box" draggable="false"></div>
            <pre v-highlight>
                <code class="javascript">

  private drag() {
        const box = document.getElementById('box') as HTMLDivElement;
        const click$ = fromEvent(box, 'click');
        const mouseDown$ = fromEvent(box, 'mousedown');
        const mouseUp$ = fromEvent(box, 'mouseup');
        const mouseout$ = fromEvent(box, 'mouseout');
        const mouseMove$ = fromEvent(box, 'mousemove');
        const stop$ = merge(mouseUp$, mouseout$);
        const BOX_OFFSET = {
            x: box.clientWidth, // div宽度，高度
            y: box.clientHeight,
        };
        const drag$ = mouseDown$.pipe(
            switchMap(e =>
                mouseMove$.pipe(
                    takeUntil(stop$),
                    map(ev => {
                        return {
                            x: (ev as any).x - (e as any).x + BOX_OFFSET.x,
                            y: (ev as any).y - (e as any).y + BOX_OFFSET.y,
                        };
                    }),
                ),
            ),
        );

        drag$.subscribe(even => {
            box.style.left = even.x + 'px';
            box.style.top = even.y + 'px';
        });
    }
                 </code>
             </pre>
            <a-card-meta
                title="相关："
                description="takeUntil，map，switchMap等操作符"
            ></a-card-meta>
        </a-card>
    </div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { fromEvent, pipe, interval, of, merge } from 'rxjs';
import {
    concatMap,
    map,
    tap,
    switchMap,
    take,
    takeUntil,
    switchMapTo,
} from 'rxjs/operators';
@Component
export default class Drag extends Vue {
    private mounted() {
        const box = document.getElementById('box') as HTMLDivElement;

        this.drag();
    }

    private drag() {
        const box = document.getElementById('box') as HTMLDivElement;
        const click$ = fromEvent(box, 'click');
        const mouseDown$ = fromEvent(box, 'mousedown');
        const mouseUp$ = fromEvent(box, 'mouseup');
        const mouseout$ = fromEvent(box, 'mouseout');
        const mouseMove$ = fromEvent(box, 'mousemove');
        const stop$ = merge(mouseUp$, mouseout$);
        const BOX_OFFSET = {
            x: box.clientWidth, // div宽度，高度
            y: box.clientHeight,
        };
        const drag$ = mouseDown$.pipe(
            switchMap(e =>
                mouseMove$.pipe(
                    takeUntil(stop$),
                    map(ev => {
                        return {
                            x: (ev as any).x - (e as any).x + BOX_OFFSET.x,
                            y: (ev as any).y - (e as any).y + BOX_OFFSET.y,
                        };
                    }),
                ),
            ),
        );

        drag$.subscribe(even => {
            box.style.left = even.x + 'px';
            box.style.top = even.y + 'px';
        });
    }
}
</script>
<style scoped>
#box {
    position: fixed;
    right: 40px;

    width: 200px;
    height: 200px;
    background: aquamarine;
    cursor: move;
}
</style>